package com.castle.fortress.admin.orders.rest;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.castle.fortress.admin.core.constants.GlobalConstants;
import com.castle.fortress.admin.member.dto.MemberDto;
import com.castle.fortress.admin.member.entity.MemberEntity;
import com.castle.fortress.admin.member.service.MemberService;
import com.castle.fortress.admin.orders.entity.SaleCouponDataEntity;
import com.castle.fortress.admin.orders.entity.SaleCouponEntity;
import com.castle.fortress.admin.orders.dto.SaleCouponDto;
import com.castle.fortress.admin.orders.enums.*;
import com.castle.fortress.admin.orders.service.SaleCouponDataService;
import com.castle.fortress.admin.system.entity.SysUser;
import com.castle.fortress.admin.orders.service.SaleCouponService;
import com.castle.fortress.common.enums.YesNoEnum;
import com.castle.fortress.common.exception.ErrorException;
import com.castle.fortress.common.utils.ConvertUtil;
import com.castle.fortress.admin.utils.WebUtil;
import com.castle.fortress.common.entity.RespBody;
import com.castle.fortress.common.exception.BizException;
import com.castle.fortress.common.respcode.GlobalRespCode;
import com.castle.fortress.common.enums.OperationTypeEnum;
import com.castle.fortress.admin.core.annotation.CastleLog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.util.Strings;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 优惠券 api 控制器
 *
 * @author whc
 * @since 2023-01-05
 */
@Api(tags = "优惠券api管理控制器")
@RestController
@RequestMapping("/api/orders/saleCoupon")
public class ApiSaleCouponController {
    @Autowired
    private SaleCouponService saleCouponService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private SaleCouponDataService saleCouponDataService;


    /**
     * 优惠券的分页展示
     *
     * @param saleCouponDto 优惠券实体类
     * @param currentPage   当前页
     * @param size          每页记录数
     * @return
     */
    @CastleLog(operLocation = "优惠券-api", operType = OperationTypeEnum.QUERY)
    @ApiOperation("优惠券分页展示")
    @GetMapping("/page")
    public RespBody<IPage<SaleCouponDto>> pageSaleCoupon(SaleCouponDto saleCouponDto, @RequestParam(required = false) Integer currentPage, @RequestParam(required = false) Integer size) {
        Integer pageIndex = currentPage == null ? GlobalConstants.DEFAULT_PAGE_INDEX : currentPage;
        Integer pageSize = size == null ? GlobalConstants.DEFAULT_PAGE_SIZE : size;
        Page<SaleCouponDto> page = new Page(pageIndex, pageSize);

        IPage<SaleCouponDto> pages = saleCouponService.pageSaleCoupon(page, saleCouponDto);
        return RespBody.data(pages);
    }

    /**
     * 优惠券保存
     *
     * @param saleCouponDto 优惠券实体类
     * @return
     */
    @CastleLog(operLocation = "优惠券-api", operType = OperationTypeEnum.INSERT)
    @ApiOperation("优惠券保存")
    @PostMapping("/save")
    public RespBody<String> saveSaleCoupon(@RequestBody SaleCouponDto saleCouponDto) {
        if (saleCouponDto == null) {
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        SaleCouponEntity saleCouponEntity = ConvertUtil.transformObj(saleCouponDto, SaleCouponEntity.class);
        if (saleCouponService.save(saleCouponEntity)) {
            return RespBody.data("保存成功");
        } else {
            return RespBody.fail(GlobalRespCode.OPERATE_ERROR);
        }
    }

    /**
     * 优惠券编辑
     *
     * @param saleCouponDto 优惠券实体类
     * @return
     */
    @CastleLog(operLocation = "优惠券-api", operType = OperationTypeEnum.UPDATE)
    @ApiOperation("优惠券编辑")
    @PostMapping("/edit")
    public RespBody<String> updateSaleCoupon(@RequestBody SaleCouponDto saleCouponDto) {
        if (saleCouponDto == null || saleCouponDto.getId() == null || saleCouponDto.getId().equals(0L)) {
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        SaleCouponEntity saleCouponEntity = ConvertUtil.transformObj(saleCouponDto, SaleCouponEntity.class);
        if (saleCouponService.updateById(saleCouponEntity)) {
            return RespBody.data("保存成功");
        } else {
            return RespBody.fail(GlobalRespCode.OPERATE_ERROR);
        }
    }

    /**
     * 优惠券删除
     *
     * @param ids 优惠券id集合
     * @return
     */
    @CastleLog(operLocation = "优惠券-api", operType = OperationTypeEnum.DELETE)
    @ApiOperation("优惠券删除")
    @PostMapping("/delete")
    public RespBody<String> deleteSaleCoupon(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        if (saleCouponService.removeByIds(ids)) {
            return RespBody.data("保存成功");
        } else {
            return RespBody.fail(GlobalRespCode.OPERATE_ERROR);
        }
    }

    /**
     * 优惠券详情
     *
     * @param id 优惠券id
     * @return
     */
    @CastleLog(operLocation = "优惠券-api", operType = OperationTypeEnum.QUERY)
    @ApiOperation("优惠券详情")
    @GetMapping("/info")
    public RespBody<SaleCouponDto> infoSaleCoupon(@RequestParam Long id) {
        if (id == null) {
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        SaleCouponEntity saleCouponEntity = saleCouponService.getById(id);
        SaleCouponDto saleCouponDto = ConvertUtil.transformObj(saleCouponEntity, SaleCouponDto.class);
        return RespBody.data(saleCouponDto);
    }


    @CastleLog(operLocation = "优惠券-api", operType = OperationTypeEnum.QUERY)
    @ApiOperation("领券中心")
    @GetMapping("/couponCenter")
    public RespBody<List<SaleCouponDto>> couponCenter() {
        //获取用户已有等级
        final MemberDto member = memberService.getByIdExtends(WebUtil.currentMember().getId());
        final Long levelId = member.getLevelId();
        //查询 符合用户等级 或者不限制等级的优惠券
        List<SaleCouponDto> dtos = saleCouponService.getMemberAvailCoupon(levelId);
        //获取用户已有优惠券计数
        final HashMap<Long, HashMap<String, Long>> longHashMapHashMap = saleCouponDataService.countGroupByMemberId(member.getId());
        //从列表中排除  不可领取的
        //返回所有当前用户可领取的优惠券
        final ArrayList<SaleCouponDto> saleCouponDtos = new ArrayList<>();
        for (SaleCouponDto dto : dtos) {
            final HashMap<String, Long> stringLongHashMap = longHashMapHashMap.get(dto.getId());
            if (stringLongHashMap != null && stringLongHashMap.get("count") != null) {
                //比较已有数量和限制数量的大小
                final int count = stringLongHashMap.get("count").intValue();
                System.out.println(count);
                System.out.println(dto.getGetMax());
                if (count < dto.getGetMax()) {
                    saleCouponDtos.add(dto);
                }
            } else {
                saleCouponDtos.add(dto);
            }
        }
        return RespBody.data(saleCouponDtos);
    }

    @CastleLog(operLocation = "优惠券-api", operType = OperationTypeEnum.OTHER)
    @ApiOperation("领取优惠券")
    @GetMapping("/receiveCoupon")
    public RespBody<String> receiveCoupon(@RequestParam Long id) {
//        final MemberDto memberDto = WebUtil.currentMember();
//
//        if (memberDto == null) {
//            throw new ErrorException(GlobalRespCode.NO_LOGIN_ERROR);
//        }
        final MemberEntity member = memberService.getById(1601104141689741314L);
        if (id == null) {
            throw new ErrorException(GlobalRespCode.PARAM_MISSED);
        }
        //查询优惠券
        final SaleCouponEntity byId = saleCouponService.getById(id);
        if (byId == null) {
            throw new ErrorException(GlobalRespCode.PARAM_MISSED);
        }
        //查询是否限制等级
        if (YesNoEnum.YES.getCode().equals(byId.getIsLimitLevel())) {
            if (!byId.getLimitLevelIds().contains(member.getLevelId().toString())) {
                throw new BizException("不符合可领取等级");
            }
        }
        //查询已有数量是否超出
        final QueryWrapper<SaleCouponDataEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_id", member.getId());
        queryWrapper.eq("coupon_id", id);
        final int count = saleCouponDataService.count(queryWrapper);
        if (count >= byId.getGetMax()) {
            throw new BizException("已超出可领取数量");
        }

        final SaleCouponDataEntity entity = new SaleCouponDataEntity();
        entity.setCouponId(id);
        entity.setMemberId(member.getId());
        entity.setGetType(CouponGetTypeEnum.RECEIVE_CENTER.getCode());
        entity.setGetTime(new Date());
        //到期时间
        if (CouponTimeLimitTypeEnum.PAYMENT.getCode().equals(byId.getTimeLimit())) {
            entity.setEffectiveTime(new Date());
            entity.setOverdueTime(new DateTime().offset(DateField.DAY_OF_YEAR, byId.getTimeDays() != null ? byId.getTimeDays() : 0).toJdkDate());
        } else if (CouponTimeLimitTypeEnum.ORDER.getCode().equals(byId.getTimeLimit())) {
            entity.setEffectiveTime(byId.getTimeStart());
            entity.setOverdueTime(byId.getTimeEnd());
        } else {
            entity.setEffectiveTime(new Date());
            entity.setOverdueTime(new Date());
        }
        entity.setStatus(CouponStatusEnum.UNUSED.getCode());
        entity.setPayType(CouponPayTypeEnum.FREE.getCode());
        entity.setPointNumber(0);
        entity.setPayNumber(0);
        saleCouponDataService.save(entity);
        return RespBody.success("操作成功");
    }
}
